import * as Cesium from 'cesium'
import { BillboardController } from './BillboardController'
import type { TypedBillboard } from '../types'

export class BillboardManager {
  private _viewer: Cesium.Viewer
  private controllers: Map<string, BillboardController>

  constructor(viewer: Cesium.Viewer) {
    this._viewer = viewer
    this.controllers = new Map()
  }

  get viewer(): Cesium.Viewer {
    return this._viewer
  }

  /**
   * 创建或获取指定类型的控制器
   * @param type
   * @param fieldMappings
   * @param defaultOptions
   * @returns
   */
  createController(type: string): BillboardController {
    if (!this.controllers.has(type)) {
      this.controllers.set(type, new BillboardController(this._viewer))
    }
    return this.controllers.get(type)!
  }

  /**
   * 获取指定类型的控制器
   * @param type
   * @returns
   */
  getController(type: string): BillboardController | undefined {
    return this.controllers.get(type)
  }

  /**
   * 检查是否存在指定类型的控制器
   * @param type Billboard类型
   * @returns 是否存在
   */
  hasController(type: string): boolean {
    return this.controllers.has(type)
  }

  /**
   * 移除指定类型的控制器
   * @param type Billboard类型
   */
  removeController(type: string): void {
    const controller = this.controllers.get(type)
    if (controller) {
      controller.destroy()
      this.controllers.delete(type)
    }
  }

  /**
   * 设置所有Billboard的可见性
   * @param visible 是否可见
   */
  setAllVisibility(visible: boolean): void {
    this.controllers.forEach((controller) => {
      controller.setAllVisibility(visible)
    })
  }

  /**
   * 设置指定类型Billboard的可见性
   * @param type Billboard类型
   * @param visible 是否可见
   */
  setVisibilityByType(type: string, visible: boolean): void {
    this.getController(type)?.setAllVisibility(visible)
  }

  /**
   * 根据 Cesium Billboard 查找对应的 TypedBillboard
   * @param cesiumBillboard Cesium 的 Billboard 实例
   * @returns TypedBillboard 实例或 null
   */
  findBillboard(cesiumBillboard: Cesium.Billboard): TypedBillboard | null {
    for (const [, controller] of this.controllers) {
      const allBillboards = controller.getAll()
      const billboard = allBillboards.find((b) => b.cesiumBillboard === cesiumBillboard)
      if (billboard) {
        return billboard
      }
    }
    return null
  }

  /**
   * 清除所有Billboard
   */
  clearAll(): void {
    this.controllers.forEach((controller) => {
      controller.clear()
    })
  }

  /**
   * 销毁所有控制器
   */
  destroy(): void {
    this.controllers.forEach((controller) => {
      controller.destroy()
    })
    this.controllers.clear()
  }
}
